package com.party.api.service.logistics.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.party.api.dto.logistics.request.LogisticsRequest;
import com.party.api.dto.logistics.request.LogisticsSystemRequest;
import com.party.api.dto.logistics.request.RequestInput;
import com.party.api.dto.logistics.request.SubscribeRequest;
import com.party.api.dto.logistics.response.LogisticsResponse;
import com.party.api.service.logistics.ILogisticsService;
import com.party.common.constant.Constant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.Map;

/**
 * @Author: Administrator.
 * @Description: 物流信息
 * @Date:Created in 2017/9/6 0006 下午 14:09.
 */
@Service
public class LogisticsService implements ILogisticsService {

    Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 即时查询接口
     *
     * @param input 请求参数
     * @return
     */
    @Override
    public LogisticsResponse getLogisticsInfo(RequestInput input) {
        String requestUrl = "http://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx";
        try {
            LogisticsRequest request = new LogisticsRequest();
            request.setLogisticCode(input.getCourierNumber());
            request.setShipperCode(input.getCourierCode());
            request.setOrderCode(input.getOrderId());

            String data = JSONObject.toJSONString(request);
            LogisticsSystemRequest systemRequest = new LogisticsSystemRequest();
            systemRequest.setRequestType("8001");
            systemRequest.seteBusinessID(input.geteBusinessID());
            systemRequest.setRequestData(URLEncoder.encode(data, Constant.UTF_8));

            String dataSign = encrypt(data, input.getApiKey(), Constant.UTF_8);
            systemRequest.setDataSign(URLEncoder.encode(dataSign, Constant.UTF_8));

            Map<String, Object> fieldValues = Maps.newHashMap();
            fieldValues.put("RequestData", systemRequest.getRequestData());
            fieldValues.put("EBusinessID", systemRequest.geteBusinessID());
            fieldValues.put("RequestType", systemRequest.getRequestType());
            fieldValues.put("DataSign", systemRequest.getDataSign());
            fieldValues.put("DataType", systemRequest.getDataType());

            logger.info("获取物流请求参数{}", JSONObject.toJSONString(fieldValues));
            String responseData = httpPost(requestUrl, fieldValues);
            logger.info("获取物流响应参数{}", responseData);

            LogisticsResponse response = JSONObject.parseObject(responseData, LogisticsResponse.class);
            return response;
        } catch (Exception e) {
            logger.error("获取物流信息异常", e);
        }
        return null;
    }

    /**
     * 轨迹订阅接口
     *
     * @param requestInput 请求信息
     * @return
     */
    @Override
    public JSONObject traceSubscribe(RequestInput requestInput) {
        String requestUrl = "http://api.kdniao.com/api/dist";
        try {
            Map<String, Object> callBackMap = Maps.newHashMap();
            callBackMap.put("orderId", requestInput.getOrderId());
            callBackMap.put("logisticsId", requestInput.getLogisticsId());

            SubscribeRequest request = new SubscribeRequest();
            request.setLogisticCode(requestInput.getCourierNumber());
            request.setShipperCode(requestInput.getCourierCode());
            request.setOrderCode(requestInput.getOrderId());
            request.setCallBack(callBackMap);
            String data = JSONObject.toJSONString(request);
            LogisticsSystemRequest systemRequest = new LogisticsSystemRequest();
            systemRequest.setRequestType("8008");
            systemRequest.seteBusinessID(requestInput.geteBusinessID());
            systemRequest.setRequestData(URLEncoder.encode(data, Constant.UTF_8));

            String dataSign = encrypt(data, requestInput.getApiKey(), Constant.UTF_8);
            systemRequest.setDataSign(URLEncoder.encode(dataSign, Constant.UTF_8));

            Map<String, Object> fieldValues = Maps.newHashMap();
            fieldValues.put("RequestData", systemRequest.getRequestData());
            fieldValues.put("EBusinessID", systemRequest.geteBusinessID());
            fieldValues.put("RequestType", systemRequest.getRequestType());
            fieldValues.put("DataSign", systemRequest.getDataSign());
            fieldValues.put("DataType", systemRequest.getDataType());

            logger.info("轨迹订阅接口请求参数{}", JSONObject.toJSONString(fieldValues));
            String responseData = httpPost(requestUrl, fieldValues);
            logger.info("轨迹订阅接口响应参数{}", responseData);
            return JSONObject.parseObject(responseData);
        } catch (Exception e) {
            logger.error("轨迹订阅接口异常", e);
        }
        return null;
    }

    /**
     * 电商Sign签名生成
     *
     * @param content  内容
     * @param keyValue Appkey
     * @param charset  编码方式
     * @return DataSign签名
     * @throws UnsupportedEncodingException ,Exception
     */
    @SuppressWarnings("unused")
    private String encrypt(String content, String keyValue, String charset) throws Exception {
        String md5Encode = MD5(content + keyValue, charset);
        byte[] encoded = org.apache.commons.codec.binary.Base64.encodeBase64(md5Encode.getBytes(charset));
        return new String(encoded);
    }

    /**
     * MD5加密
     *
     * @param str     内容
     * @param charset 编码方式
     * @throws Exception
     */
    @SuppressWarnings("unused")
    private String MD5(String str, String charset) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(str.getBytes(charset));
        byte[] result = md.digest();
        StringBuffer sb = new StringBuffer(32);
        for (int i = 0; i < result.length; i++) {
            int val = result[i] & 0xff;
            if (val <= 0xf) {
                sb.append("0");
            }
            sb.append(Integer.toHexString(val));
        }
        return sb.toString().toLowerCase();
    }

    public String httpPost(String requestUrl, Map<String, Object> params) {
        OutputStreamWriter out = null;
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        try {
            URL realUrl = new URL(requestUrl);
            HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // POST方法
            conn.setRequestMethod("POST");
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            conn.connect();
            // 获取URLConnection对象对应的输出流
            out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
            // 发送请求参数
            if (params != null) {
                StringBuilder param = new StringBuilder();
                for (Map.Entry<String, Object> entry : params.entrySet()) {
                    if (param.length() > 0) {
                        param.append("&");
                    }
                    param.append(entry.getKey());
                    param.append("=");
                    param.append(entry.getValue());
                }
                out.write(param.toString());
            }
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result.toString();
    }

    public static void main(String[] args) {
        ILogisticsService logisticsService = new LogisticsService();
        RequestInput input = new RequestInput();
        input.seteBusinessID("1372566");
        input.setApiKey("5655c124-b09d-4c8e-a1d8-9c85258a13a3");
        input.setCourierCode("HTKY");
        input.setCourierNumber("71244185057094");
        LogisticsResponse logisticsInfo = logisticsService.getLogisticsInfo(input);
    }
}
